package com.anuo.app.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 日期工具类
 */
public class DateUtil extends org.apache.commons.lang3.time.DateUtils {

    public final static String PATTERN_HYPHEN_DATE = "yyyy-MM-dd";
    public final static String PATTERN_HYPHEN_DATETIME = "yyyy-MM-dd HH:mm:ss";
    public final static String PATTERN_SLASH_DATE = "yyyy/MM/dd";
    public final static String PATTERN_SLASH_DATETIME = "yyyy/MM/dd HH:mm:ss";

    //region 获取当前日期, 日期某个部分

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd）
     */
    public static String getCurrentDate() {
        return DateFormatUtils.format(new Date(), DateUtil.PATTERN_HYPHEN_DATE);
    }

    /**
     * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String getCurrentDateTime() {
        return formatDate(new Date(), DateUtil.PATTERN_HYPHEN_DATETIME);
    }

    /**
     * 获取日期字符串,会抹掉时间部分 格式（yyyy-MM-dd）
     *
     * @return
     */
    public static String getDateString(Date date) {
        return DateFormatUtils.format(date, DateUtil.PATTERN_HYPHEN_DATE);
    }

    /**
     * 获取日期,会抹掉时间部分 格式（yyyy-MM-dd）
     *
     * @param date
     * @return
     */
    public static Date getDate(Date date) {
        return strToDate(DateFormatUtils.format(date, DateUtil.PATTERN_HYPHEN_DATE));
    }


    /**
     * 得到年份字符串 格式（yyyy）
     */
    public static String getYear(Date date) {
        return formatDate(date, "yyyy");
    }

    /**
     * 得到年份整型
     */
    public static int getYearInt(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.get(Calendar.YEAR);

    }

    /**
     * 得到当前年份字符串 格式（yyyy）
     */
    public static String getCurrentYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 返回当前年份(整型)
     *
     * @return
     */
    public static int getCurrentYearInt() {
        return Calendar.getInstance().get(Calendar.YEAR);
    }

    /**
     * 得到当前月份字符串 格式（MM）
     */
    public static String getMonth(Date date) {
        return formatDate(date, "MM");
    }

    /**
     * 得到当天字符串 格式（dd）
     */
    public static String getDay(Date date) {
        return formatDate(date, "dd");
    }

    /**
     * 得到当前星期字符串 格式（E）星期几
     */
    public static String getWeek(Date date) {
        return formatDate(date, "E");
    }

    //endregion 获取当前日期, 日期某个部分

    //region 日期转换

    /**
     * 按照yyyy-MM-dd HH:mm:ss的格式，日期转字符串
     *
     * @param date
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String dateToStr(Date date) {
        return dateToStr(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 按照参数format的格式，日期转字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String dateToStr(Date date, String format) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        } else {
            return "";
        }
    }

    /**
     * 字符串转日期时间,包含时分秒 (可以传 - 或 / 格式日期, 注意必须传时分秒, 不然解析不出来)
     *
     * @param date
     * @return
     */
    public static Date strToDate(String date) {
        if (StringUtils.isNotEmpty(date)) {
            SimpleDateFormat sdf = new SimpleDateFormat();

            if (date.contains("-") && date.contains("HH")) {
                sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            } else if (date.contains("/") && date.contains("HH")) {
                sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            } else {
                sdf = new SimpleDateFormat("yyyy-MM-dd");
            }

            try {
                return sdf.parse(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return new Date();
        } else {
            return null;
        }
    }

//	public static String strToDateShort(String date){
//		if (StringUtils.isNotEmpty(date)) {
//			SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
//			return "";
//		} else {
//			return "传入的日期字符串不能为空";
//		}
//	}

    /**
     * 格式化日期 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

    /**
     * 格式化日期时间，转换格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }
    //endregion 日期转换

    //region 日期计算

    /**
     * 获取两个日期之间的天数
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }

    /**
     * 在当前时间上加指定的天数
     *
     * @param days
     * @return
     */
    public static Date addDaysToCurrentTime(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, days);
        return calendar.getTime();
    }

    /**
     * 在指定的日期上加减天数
     *
     * @param date
     * @param days 正数为加, 负数为减
     * @return
     */
    public static Date addSubtractDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);

        return calendar.getTime();
    }

    /**
     * 在指定的日期上加减分钟数
     *
     * @param date
     * @param minutes 正数为加, 负数为减
     * @return
     */
    public static Date addSubtractMinute(Date date, int minutes) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minutes);
        return calendar.getTime();
    }

    /**
     * 在指定的日期上加减秒
     *
     * @param date
     * @param seconds 正数为加, 负数为减
     * @return
     */
    public static Date addSubtractSecond(Date date, int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        return calendar.getTime();
    }

    /**
     * 获取日期最大值
     *
     * @return
     */
    public static Date getDateMaxValue() {
        return new Date(Long.MAX_VALUE);
    }

    /**
     * 获取日期最小值
     *
     * @return
     */
    public static Date getDateMinValue() {
        return new Date(Long.MIN_VALUE);
    }

    /**
     * 获取指定日期当天最大值, 如 2018-01-01 00:00:00 , 返回 2018-01-01 59:59:59
     *
     * @param date
     * @return
     */
    public static Date getThisDayMaxValue(Date date) {
        Date newDate = addSubtractSecond(addSubtractDays(date, 1), -1);
        return newDate;
    }
    //endregion 日期计算

    public static Calendar getCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    public static Date getMaxDate() {
        String maxDateStr = "9999-12-31 00:00:00";
        return strToDate(maxDateStr);
    }

    public static long dayToSecond(int days) {
        return TimeUnit.DAYS.toMillis(days) / 1000;
    }

    /**
     * 小时转秒
     * 参考:https://stackoverflow.com/questions/6980376/convert-from-days-to-milliseconds
     *
     * @param hours
     * @return
     */
    public static long hourToSecond(int hours) {
        return TimeUnit.HOURS.toMillis(hours) / 1000;
    }

    /**
     * 将date 转为unix time
     *
     * @param date
     * @return
     */
    public static long dateToUnixTime(Date date) {
        return date.getTime() / 1000L;
    }

    /**
     * 将unixTime 转为Date
     *
     * @param unixTime
     * @return
     */
    public static Date convertUnixTimeToDate(long unixTime) {
        return new Date(unixTime * 1000L);
    }

    public static long nanoTimeToMillisecond(long nanoTime){
        return  nanoTime/1000000;
    }

    /**
     * 获取时间戳
     * @return
     */
    public static String getTimestamp(){
        return Long.toString(System.currentTimeMillis() / 1000);
    }

    public static void main(String[] args) {
        Date date = strToDate("2017-08-03 19:00:00");

        Date date2 = getDate(date);

        System.out.println(dateToStr(date2));
    }

}
